package com.lzh.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.lzh.admin.entity.AdChannel;
import com.lzh.admin.mapper.AdSensitiveMapper;
import com.lzh.admin.service.AdChannelService;
import com.lzh.admin.service.WemediaNewsAutoScanService;
import com.lzh.article.dto.ArticleInfoDto;
import com.lzh.article.entity.ApArticle;
import com.lzh.article.entity.ApArticleConfig;
import com.lzh.article.entity.ApArticleContent;
import com.lzh.article.entity.ApAuthor;
import com.lzh.article.feign.ApArticleFeign;
import com.lzh.article.feign.ApAuthorFeign;
import com.lzh.common.aliyun.GreenImageScan;
import com.lzh.common.aliyun.GreenTextScan;
import com.lzh.common.aliyun.ScanConstants;
import com.lzh.common.aliyun.SensitiveWordUtil;
import com.lzh.common.constants.BusinessConstants;
import com.lzh.common.pojo.Result;
import com.lzh.dfs.feign.DfsFeign;
import com.lzh.media.dto.ContentNode;
import com.lzh.media.entity.WmNews;
import com.lzh.media.feign.WmNewsFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author lizuhu
 * @description
 * @date 2021/7/1 18:53
 */
@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Autowired
    private WmNewsFeign wmNewsFeign;

    @Autowired
    private DfsFeign dfsFeign;

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private GreenImageScan greenImageScan;

    @Resource
    private AdSensitiveMapper adSensitiveMapper;

    @Autowired
    private ApArticleFeign apArticleFeign;

    @Autowired
    private ApAuthorFeign apAuthorFeign;

    @Autowired
    private AdChannelService adChannelService;


    @Override
    public void autoScanByMediaNewsId(Integer id) throws Exception {//数据需要进行同步

        //1.根据ID 获取自媒体文章信息
        WmNews wmNews = wmNewsFeign.getById(id).getData();
        if (wmNews != null) {
            //2.获取审核的文本 和 图片
            //2.1 获取文本图片结合
            String content = wmNews.getContent();
            //2.2 获取图片合并列表
            List<String> imagesFromContent = getImagesFromContent(content, wmNews.getImages());

            //2.3获取文本合并列表
            List<String> textFromContent = getTextFromContent(content, wmNews.getTitle());

            //3 进行自动审核
            String status = scanTextAndImage(textFromContent, imagesFromContent);

            //判断是否状态为9 如果是9 才需要进行创建文章 （在8的时候也不行，当后面我们实现功能XXL-JOB进行更新的时候 再进行调用）
            boolean flag=false;
            switch (status) {
                // 如果是 拒绝 则更新状态 为【审核失败】
                case ScanConstants.BLOCK: {
                    WmNews record = new WmNews();
                    record.setId(id);
                    record.setStatus(2);
                    record.setReason("文本或图片违规");
                    wmNewsFeign.updateByPrimaryKey(record);
                    break;
                }
                // 如果是 审核成功 则更新状态根据情况来进行处理   1如果是发布时间为null 则 更新为9 ; 2: 如果是发布时间不为null 则更新为8
                case ScanConstants.PASS: {
                    if (wmNews.getPublishTime() != null) {
                        WmNews record = new WmNews();
                        record.setId(id);
                        record.setStatus(8);
                        wmNewsFeign.updateByPrimaryKey(record);
                    } else {
                        WmNews record = new WmNews();
                        record.setId(id);
                        record.setStatus(9);
                        flag=true;
                        wmNewsFeign.updateByPrimaryKey(record);
                    }
                    break;
                }
                // 如果是 不确定 则人工审核
                case ScanConstants.REVIEW: {
                    WmNews record = new WmNews();
                    record.setId(id);
                    record.setStatus(3);
                    wmNewsFeign.updateByPrimaryKey(record);
                    break;
                }
                default:
                    System.out.println("错误信息");
                    break;
            }
            //4.保存文章相关信息 并进行状态同步 涉及到三个表 article article_content article_config
            if(flag) {
                ArticleInfoDto articleInfoDto = new ArticleInfoDto();

                ApArticle article = new ApArticle();

                //该值有可能为null
                if (wmNews.getArticleId() != null) {
                    article.setId(wmNews.getArticleId());
                }
                article.setTitle(wmNews.getTitle());
                //根据自媒体账号获取作者信息
                //自媒体账号ID
                ApAuthor apAuthor = apAuthorFeign.getByUserId(wmNews.getUserId());
                if (apAuthor != null) {
                    article.setAuthorId(apAuthor.getId());
                    article.setAuthorName(apAuthor.getName());
                }
                //获取频道
                AdChannel adChannel = adChannelService.getById(wmNews.getChannelId());
                if (adChannel != null) {
                    article.setChannelId(adChannel.getId());
                    article.setChannelName(adChannel.getName());
                }
                //文章布局
                article.setLayout(wmNews.getType());
                //普通文章
                article.setFlag(0);

                article.setImages(wmNews.getImages());

                article.setLabels(wmNews.getLabels());

                if (wmNews.getPublishTime() != null) {
                    article.setPublishTime(wmNews.getPublishTime());
                }
                //同步状态
                article.setSyncStatus(wmNews.getStatus());
                articleInfoDto.setApArticle(article);

                ApArticleConfig articleConfig = new ApArticleConfig();
                //设置默认值
                articleConfig.setIsDown(0);
                //设置默认值
                articleConfig.setIsDelete(0);
                articleInfoDto.setApArticleConfig(articleConfig);
                ApArticleContent articleContent = new ApArticleContent();
                //内容
                articleContent.setContent(wmNews.getContent());
                articleInfoDto.setApArticleContent(articleContent);
                //获取到文章的ID
                Result<ApArticle> resultApArticle = apArticleFeign.save(articleInfoDto);

                ApArticle data = resultApArticle.getData();
                //获取ID 更新到自媒体表当中
                Long articleId = data.getId();
                WmNews record = new WmNews();
                record.setId(id);
                record.setArticleId(articleId);
                wmNewsFeign.updateByPrimaryKey(record);
            }
        }
    }

    //获取图片
    private List<String> getImagesFromContent(String content, String images) {
        //1.定义一个List 用来封装所有的图片路径
        List<String> imagesAllList  = new ArrayList<String>();
        if(!StringUtils.isEmpty(content)) {
            //2.将content 转成 List<ContentNode>
            List<ContentNode> contentNodes = JSON.parseArray(content, ContentNode.class);

            //3.循环遍历获取到type类型为image的value的值 添加到list中
            for (ContentNode contentNode : contentNodes) {
                if(contentNode.getType().equals("image")){
                    imagesAllList.add(contentNode.getValue());
                }
            }
        }
        //images的数据格式：12345.jpg
        if(!StringUtils.isEmpty(images)) {
            //4.将 images 添加list
            String[] split = images.split(",");
            List<String> imagesList = Arrays.asList(split);
            imagesAllList.addAll(imagesList);
        }
        //5.返回list
        return imagesAllList;
    }

    //获取文本并合并
    private List<String> getTextFromContent(String content, String title) {
        //1.定义一个List 用来封装所有的文本
        List<String> texts  = new ArrayList<String>();

        if(!StringUtils.isEmpty(content)) {
            //2.将content 转成 List<ContentNode>
            List<ContentNode> contentNodes = JSON.parseArray(content, ContentNode.class);
            //3.循环遍历获取到type类型为text的value的值 添加到list中
            for (ContentNode contentNode : contentNodes) {
                if (contentNode.getType().equals("text")) {
                    texts.add(contentNode.getValue());
                }
            }
        }
        //4.将title 添加list
        texts.add(title);
        //5.返回list
        return texts;
    }


    //阿里云文本和图片审核 以及 敏感词审核
    private String scanTextAndImage(List<String> texts, List<String> images) throws Exception {
        //1审核文本
        if (texts != null) {
            Map map = greenTextScan.greeTextScan(texts);
            String result1 = getScanResult(map);
            //如果不成功 则直接返回 不需要执行了
            if (!result1.equals(ScanConstants.PASS)) {
                return result1;
            }
        }


        //2 审核 图片
        if (images != null) {
            List<byte[]> bytes = dfsFeign.downLoadFile(images);
            Map map = greenImageScan.imageScan(bytes);
            String result2 = getScanResult(map);
            //如果不成功 则直接返回 不需要执行了
            if (!result2.equals(BusinessConstants.ScanConstants.PASS)) {
                return result2;
            }
        }
        if(texts!=null) {
            //3 审核敏感词
            List<String> adSensitives = adSensitiveMapper.selectSensitives();
            //这个可以优化放到缓存中
            SensitiveWordUtil.initMap(adSensitives);
            //扫描并判断是否正确DynamicServerListLoadBalancer
            for (String text : texts) {
                Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
                if (stringIntegerMap.size() > 0) {
                    return BusinessConstants.ScanConstants.BLOCK;
                }
            }
        }
        //通过
        return BusinessConstants.ScanConstants.PASS;
    }

    //封装
    private String getScanResult(Map map) {
        Object suggestion = map.get("suggestion");
        if (!suggestion.equals("pass")) {
            //有敏感词
            if (suggestion.equals("block")) {
                return BusinessConstants.ScanConstants.BLOCK;
            }
            //人工审核
            if (suggestion.equals("review")) {
                return BusinessConstants.ScanConstants.REVIEW;
            }
        }
        //如果没错误 返回成功
        return BusinessConstants.ScanConstants.PASS;
    }
}
